//*******************************************************************       //
//IMPORTANT NOTICE                                                          //
//================                                                          //
//Copyright Mentor Graphics Corporation 1996 - 1999.  All rights reserved.  //
//This file and associated deliverables are the trade secrets,              //
//confidential information and copyrighted works of Mentor Graphics         //
//Corporation and its licensors and are subject to your license agreement   //
//with Mentor Graphics Corporation.                                         //
//                                                                          //
//Use of these deliverables for the purpose of making silicon from an IC    //
//design is limited to the terms and conditions of your license agreement   //
//with Mentor Graphics If you have further questions please contact Mentor  //
//Graphics Customer Support.                                                //
//                                                                          //
//This Mentor Graphics core (m8051w v2002.080) was extracted on             //
//workstation hostid 8316cbec Inventra                                      //
// ALU Operand Selector for M8051W/EW
// 
// $Log: m3s004dy.v,v $
// Revision 1.4  2001/11/20
// First checkin of version 2 features and name change
//
// Revision 1.2  2001/10/31
// First parsable verilog for EW
//
// Revision 1.1.1.1  2001/07/17
// Re-imported E-Warp from Farnham filesystem
//
// Revision 1.3  2000/02/05
// Name change repercussions
//
// Revision 1.2  1999/11/30
// More debug changes.
//
// Revision 1.1.1.1  1999/10/28
// "initialization and source check-in for m8051e"
//
// Revision 1.1  1999/10/22
// Initial revision
//
////////////////////////////////////////////////////////////////////////////////

module m3s004dy( OPERAND_A, OPERAND_B, ACC, PSW, SOURCE_DI, SFR_DATA,
//*******************************************************************       //
//IMPORTANT NOTICE                                                          //
//================                                                          //
//Copyright Mentor Graphics Corporation 1996 - 1999.  All rights reserved.  //
//This file and associated deliverables are the trade secrets,              //
//confidential information and copyrighted works of Mentor Graphics         //
//Corporation and its licensors and are subject to your license agreement   //
//with Mentor Graphics Corporation.                                         //
//                                                                          //
//Use of these deliverables for the purpose of making silicon from an IC    //
//design is limited to the terms and conditions of your license agreement   //
//with Mentor Graphics If you have further questions please contact Mentor  //
//Graphics Customer Support.                                                //
//                                                                          //
//This Mentor Graphics core (m8051w v2002.080) was extracted on             //
//workstation hostid 8316cbec Inventra                                      //
                 IMMEDIATE, SWITCH_CON, SOURCE_IS_SFR);

  output [7:0] OPERAND_A;
  output [7:0] OPERAND_B;
  input  [7:0] ACC;
  input  [7:6] PSW;
  input  [7:0] SOURCE_DI, SFR_DATA;
  input  [7:0] IMMEDIATE;
  input  [5:0] SWITCH_CON;
  input  SOURCE_IS_SFR;

  wire   [7:0] OPERAND_DAA;
  wire   [7:0] NUMBER_CONSTANT;
  wire   [7:0] MUXED_DATA;

  // Calculate DAA adjustment operand based upon current value of accumulator,
  // carry and auxilliary carry flags.
  // Use acc lower nibble and aux carry to decide whether to adjust lower nibble

  assign OPERAND_DAA[3:0] = (PSW[6] || ACC[3:0] > 4'd9)? 4'd6: 4'd0;
 
  // Use acc high nibble, previous carry and predicted result of any low nibble
  // adjustment to decide whether to adjust high nibble by six.

  assign OPERAND_DAA[7:4] = (PSW[7] || ACC[7:4] >4'd9 || 
                            (ACC[7:4] == 4'd9 && ACC[3:0] > 4'h9))?
                            4'd6: 4'd0;

  // ALU Operand data multiplexers

  // Select a constant number as an ALU operand
  // one for increments and decrements; acc-related constant for decimal adjust.

  assign NUMBER_CONSTANT = SWITCH_CON[5]? OPERAND_DAA: 8'h01;

  // OPERAND_A may be either the accumulator, data memory or an SFR,
  // OPERAND_B may be either immediate data, a number constant, data memory or
  // an SFR.
 
  // Mutiplex SFR read data with internal memory data.

  assign MUXED_DATA = SOURCE_IS_SFR ? SFR_DATA: SOURCE_DI; 

  // ALU operands multiplexers:

  assign OPERAND_A = ({8{SWITCH_CON[0]}} & ACC)                                |
                     ({8{SWITCH_CON[1]}} & MUXED_DATA);

  assign OPERAND_B = ({8{SWITCH_CON[2]}} & MUXED_DATA)                         |
                     ({8{SWITCH_CON[3]}} & IMMEDIATE)                          |
                     ({8{SWITCH_CON[4]}} & NUMBER_CONSTANT);

endmodule
